package goinput

import (
	"bytes"
	"errors"
)

// Key combination to trigger an event.
type Key struct {
	// Byte code of the key.
	Code [][]byte
	// User data.
	Data []any
	// User documentation.
	Doc string
	// Key event.
	EventFunc func(key *Key) error
}

// Clear key.Code and return key.
func (key *Key) Clear() *Key {
	key.Code = [][]byte{}

	return key
}

// Compile key according to name.
func (key *Key) compile(name string) (err error) {
	var (
		codeTmp [][]byte
		flag    = struct {
			Whitespace bool
		}{
			Whitespace: true,
		}
	)

	switch {
	case 0 != len(key.Code):
		return
	case 0 == len(name):
		return errors.New("name cannot be empty")
	}

	for symbolNum, symbol := range name {
		switch symbol {
		case ' ':
			switch {
			case flag.Whitespace:
				return errors.New("name has too many spaces")
			case symbolNum == len(name)-1:
				return errors.New("name cannot end with a space")
			}

			flag.Whitespace = true
		default:
			if !flag.Whitespace {
				return errors.New("name does not have enough spaces")
			}

			flag.Whitespace = false

			codeTmp = append(codeTmp, []byte(string(symbol)))
		}
	}

	key.Code = codeTmp

	return
}

// Return the equality state of key.Code[pairNum] and code.
func (key *Key) Equal(code []byte, pairNum int) bool {
	return bytes.Equal(key.Code[pairNum], code)
}

// Call EventFunc by passing key.
func (key *Key) Event() error {
	return key.EventFunc(key)
}

// Return the length of key.Code.
func (key *Key) Len() int {
	return len(key.Code)
}
